#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
Redis COM Server for Classic ASP
完美支持中文的Redis COM组件
适用于经典ASP项目的现代化升级

功能特性：
1. 完整的Redis操作支持
2. 中文内容Base64编码存储
3. UTF-8编码完美兼容
4. 线程安全和超时保护
5. 完善的错误处理

使用方法：
1. 注册组件：python redis_com_server.py
2. 在ASP中使用：Server.CreateObject("RedisCOM.Server")

作者：AI Assistant
版本：1.0.0 - Production Ready
"""

import pythoncom
import sys
import json
import datetime
import threading
import queue
import base64
from win32com.server import util

class RedisCOMServer:
    """Redis COM服务器 - 生产级别"""
    _public_methods_ = [
        # 基础Redis操作
        'RedisSet', 'RedisGet', 'RedisDelete', 'RedisExists', 'RedisKeys',
        # 中文专用操作
        'RedisSetChinese', 'RedisGetChinese', 'RedisSetJSON', 'RedisGetJSON',
        # 高级操作
        'RedisIncr', 'RedisExpire', 'RedisGetTTL',
        # 系统功能
        'GetSystemInfo', 'CheckStatus', 'TestConnection'
    ]
    _reg_progid_ = "RedisCOM.Server"
    _reg_clsid_ = pythoncom.CreateGuid()
    _reg_desc_ = "Redis COM Server for Classic ASP - Chinese Support"

    def __init__(self):
        """初始化Redis COM服务器"""
        self.version = "1.0.0"
        self.created_at = datetime.datetime.now()
        # Redis连接配置（可根据需要修改）
        self.redis_host = '10.0.0.204'
        self.redis_port = 6379
        self.redis_password = '123456'

    def _safe_execute(self, func, args=(), timeout=30):
        """线程安全执行，带超时保护"""
        result_queue = queue.Queue()

        def worker():
            try:
                result = func(*args)
                result_queue.put({"success": result})
            except Exception as e:
                result_queue.put({"error": str(e)})

        thread = threading.Thread(target=worker, daemon=True)
        thread.start()
        thread.join(timeout)

        if thread.is_alive():
            return {"error": f"Operation timeout ({timeout}s)"}

        try:
            return result_queue.get_nowait()
        except queue.Empty:
            return {"error": "No result returned"}

    def _get_redis_connection(self):
        """获取Redis连接"""
        import redis
        return redis.Redis(
            host=self.redis_host,
            port=self.redis_port,
            password=self.redis_password,
            decode_responses=True
        )

    def _format_json_safe(self, data):
        """安全格式化JSON，确保ASP兼容"""
        try:
            return json.dumps(data, indent=2, ensure_ascii=True)
        except Exception as e:
            return f'{{"error": "JSON format failed: {str(e)}"}}'

    def _encode_chinese(self, text):
        """中文编码为Base64"""
        try:
            if isinstance(text, str):
                utf8_bytes = text.encode('utf-8')
                return base64.b64encode(utf8_bytes).decode('ascii')
            return text
        except Exception as e:
            return f"Encoding error: {str(e)}"

    def _decode_chinese(self, base64_text):
        """Base64解码为中文"""
        try:
            utf8_bytes = base64.b64decode(base64_text.encode('ascii'))
            return utf8_bytes.decode('utf-8')
        except Exception as e:
            return f"Decoding error: {str(e)}"

    # ==================== 基础Redis操作 ====================
    def RedisSet(self, key, value, expire_seconds=0):
        """Redis设置键值对"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                if expire_seconds > 0:
                    r.setex(key, expire_seconds, value)
                    return f"Success: Key '{key}' set with {expire_seconds}s expiry"
                else:
                    r.set(key, value)
                    return f"Success: Key '{key}' set successfully"
            except ImportError:
                return "Error: Redis library not installed - pip install redis"
            except Exception as e:
                return f"Error: Redis operation failed - {str(e)}"

        result = self._safe_execute(redis_operation, timeout=10)
        return result.get("success", result.get("error", "Unknown error"))

    def RedisGet(self, key):
        """Redis获取值"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                value = r.get(key)

                if value is not None:
                    return {
                        "found": True,
                        "key": key,
                        "value": value,
                        "type": type(value).__name__,
                        "length": len(str(value))
                    }
                else:
                    return {
                        "found": False,
                        "key": key,
                        "message": "Key not found or expired"
                    }
            except Exception as e:
                return {"error": f"Redis read failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    def RedisDelete(self, key):
        """Redis删除键"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                deleted = r.delete(key)
                return f"Success: {deleted} key(s) deleted"
            except Exception as e:
                return f"Error: Redis delete failed - {str(e)}"

        result = self._safe_execute(redis_operation, timeout=5)
        return result.get("success", result.get("error", "Unknown error"))

    def RedisExists(self, key):
        """检查Redis键是否存在"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                exists = r.exists(key)
                return {
                    "key": key,
                    "exists": bool(exists),
                    "message": "Key exists" if exists else "Key does not exist"
                }
            except Exception as e:
                return {"error": f"Redis exists check failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    def RedisKeys(self, pattern="*"):
        """Redis获取键列表"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                keys = r.keys(pattern)
                return {
                    "pattern": pattern,
                    "count": len(keys),
                    "keys": keys[:50]  # 限制返回前50个
                }
            except Exception as e:
                return {"error": f"Redis keys failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    # ==================== 中文专用操作 ====================
    def RedisSetChinese(self, key, chinese_text, expire_seconds=0):
        """Redis设置中文内容（Base64编码）"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                encoded_text = self._encode_chinese(chinese_text)

                if expire_seconds > 0:
                    r.setex(key, expire_seconds, encoded_text)
                    return f"Success: Chinese key '{key}' set with {expire_seconds}s expiry"
                else:
                    r.set(key, encoded_text)
                    return f"Success: Chinese key '{key}' set successfully"
            except Exception as e:
                return f"Error: Chinese set failed - {str(e)}"

        result = self._safe_execute(redis_operation, timeout=10)
        return result.get("success", result.get("error", "Unknown error"))

    def RedisGetChinese(self, key):
        """Redis获取中文内容（自动解码）"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                encoded_value = r.get(key)

                if encoded_value is not None:
                    decoded_text = self._decode_chinese(encoded_value)
                    return {
                        "found": True,
                        "key": key,
                        "chinese_text": decoded_text,
                        "base64_encoded": encoded_value,
                        "encoding": "UTF-8 via Base64"
                    }
                else:
                    return {
                        "found": False,
                        "key": key,
                        "message": "Chinese key not found or expired"
                    }
            except Exception as e:
                return {"error": f"Chinese get failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    def RedisSetJSON(self, key, json_data, expire_seconds=0):
        """Redis设置JSON数据（支持中文）"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                # 将JSON数据编码为Base64存储
                json_str = json.dumps(json_data, ensure_ascii=False) if isinstance(json_data, (dict, list)) else str(json_data)
                encoded_json = self._encode_chinese(json_str)

                if expire_seconds > 0:
                    r.setex(key, expire_seconds, encoded_json)
                    return f"Success: JSON key '{key}' set with {expire_seconds}s expiry"
                else:
                    r.set(key, encoded_json)
                    return f"Success: JSON key '{key}' set successfully"
            except Exception as e:
                return f"Error: JSON set failed - {str(e)}"

        result = self._safe_execute(redis_operation, timeout=10)
        return result.get("success", result.get("error", "Unknown error"))

    def RedisGetJSON(self, key):
        """Redis获取JSON数据（自动解码）"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                encoded_value = r.get(key)

                if encoded_value is not None:
                    decoded_json_str = self._decode_chinese(encoded_value)
                    try:
                        parsed_json = json.loads(decoded_json_str)
                        return {
                            "found": True,
                            "key": key,
                            "json_data": parsed_json,
                            "raw_string": decoded_json_str,
                            "encoding": "JSON via UTF-8 Base64"
                        }
                    except json.JSONDecodeError:
                        return {
                            "found": True,
                            "key": key,
                            "raw_string": decoded_json_str,
                            "note": "Not valid JSON, returned as string"
                        }
                else:
                    return {
                        "found": False,
                        "key": key,
                        "message": "JSON key not found or expired"
                    }
            except Exception as e:
                return {"error": f"JSON get failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    # ==================== 高级操作 ====================
    def RedisIncr(self, key, increment=1):
        """Redis递增操作"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                new_value = r.incr(key, increment)
                return {
                    "key": key,
                    "new_value": new_value,
                    "increment": increment,
                    "message": f"Key '{key}' incremented by {increment}"
                }
            except Exception as e:
                return {"error": f"Redis increment failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    def RedisExpire(self, key, seconds):
        """Redis设置过期时间"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                success = r.expire(key, seconds)
                return {
                    "key": key,
                    "expires_in": seconds,
                    "success": bool(success),
                    "message": f"Expiry set for {seconds}s" if success else "Key not found"
                }
            except Exception as e:
                return {"error": f"Redis expire failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    def RedisGetTTL(self, key):
        """Redis获取剩余过期时间"""
        def redis_operation():
            try:
                r = self._get_redis_connection()
                ttl = r.ttl(key)
                if ttl == -2:
                    message = "Key does not exist"
                elif ttl == -1:
                    message = "Key exists but has no expiry"
                else:
                    message = f"Key expires in {ttl} seconds"

                return {
                    "key": key,
                    "ttl_seconds": ttl,
                    "message": message
                }
            except Exception as e:
                return {"error": f"Redis TTL failed: {str(e)}"}

        result = self._safe_execute(redis_operation, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    # ==================== 系统功能 ====================
    def TestConnection(self):
        """测试Redis连接"""
        def test_connection():
            try:
                r = self._get_redis_connection()
                ping_result = r.ping()
                info = r.info('server')

                return {
                    "connection": "Success",
                    "ping": ping_result,
                    "redis_version": info.get('redis_version', 'Unknown'),
                    "server": f"{self.redis_host}:{self.redis_port}",
                    "test_time": datetime.datetime.now().isoformat()
                }
            except Exception as e:
                return {"error": f"Connection test failed: {str(e)}"}

        result = self._safe_execute(test_connection, timeout=5)
        if "success" in result:
            return self._format_json_safe(result["success"])
        else:
            return self._format_json_safe(result)

    def CheckStatus(self):
        """检查组件状态"""
        try:
            import redis
            redis_version = getattr(redis, '__version__', 'Unknown')
        except ImportError:
            redis_version = 'Not installed'

        status = {
            "com_version": self.version,
            "python_version": sys.version.split()[0],
            "redis_library": redis_version,
            "created_at": self.created_at.strftime("%Y-%m-%d %H:%M:%S"),
            "current_time": datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "redis_server": f"{self.redis_host}:{self.redis_port}",
            "features": [
                "Basic Redis Operations",
                "Chinese Text Support via Base64",
                "JSON Data Handling",
                "Advanced Redis Commands",
                "Thread-Safe Operations",
                "Timeout Protection"
            ]
        }
        return self._format_json_safe(status)

    def GetSystemInfo(self):
        """获取系统信息"""
        info = {
            "component": "Redis COM Server",
            "version": self.version,
            "description": "Production-ready Redis COM component for Classic ASP",
            "python_version": sys.version,
            "capabilities": {
                "basic_operations": ["set", "get", "delete", "exists", "keys"],
                "chinese_support": ["utf8_encoding", "base64_storage", "automatic_decode"],
                "advanced_features": ["increment", "expire", "ttl", "json_handling"],
                "safety_features": ["thread_safe", "timeout_protection", "error_handling"]
            },
            "usage_example": {
                "asp_create": "Set obj = Server.CreateObject(\"RedisCOM.Server\")",
                "basic_set": "obj.RedisSet(\"key\", \"value\", 300)",
                "chinese_set": "obj.RedisSetChinese(\"中文键\", \"中文内容\", 300)",
                "json_set": "obj.RedisSetJSON(\"data\", jsonData, 300)"
            }
        }
        return self._format_json_safe(info)

def register_redis_com():
    """注册Redis COM组件"""
    try:
        import win32com.server.register
        win32com.server.register.UseCommandLine(RedisCOMServer)
        print("✅ RedisCOM.Server 注册成功")
        print(f"ProgID: {RedisCOMServer._reg_progid_}")
        print(f"CLSID: {RedisCOMServer._reg_clsid_}")
        print("\n📋 使用方法:")
        print("1. 在ASP中创建对象: Server.CreateObject(\"RedisCOM.Server\")")
        print("2. 基础操作: obj.RedisSet(\"key\", \"value\", 300)")
        print("3. 中文操作: obj.RedisSetChinese(\"key\", \"中文内容\", 300)")
        print("4. JSON操作: obj.RedisSetJSON(\"key\", jsonData, 300)")
        return True
    except Exception as e:
        print(f"❌ 注册失败: {e}")
        return False

def test_redis_com():
    """测试Redis COM组件"""
    try:
        import win32com.client
        obj = win32com.client.Dispatch("RedisCOM.Server")

        print("\n🧪 测试RedisCOM.Server:")

        print("\n1. 系统信息:")
        print(obj.GetSystemInfo())

        print("\n2. 连接测试:")
        print(obj.TestConnection())

        print("\n3. 基础操作测试:")
        print("设置:", obj.RedisSet("test_basic", "Hello Redis", 300))
        print("读取:", obj.RedisGet("test_basic"))

        print("\n4. 中文操作测试:")
        print("设置中文:", obj.RedisSetChinese("test_chinese", "你好，Redis！", 300))
        print("读取中文:", obj.RedisGetChinese("test_chinese"))

        print("\n5. JSON操作测试:")
        json_data = '{"name": "张三", "age": 25, "city": "北京"}'
        print("设置JSON:", obj.RedisSetJSON("test_json", json_data, 300))
        print("读取JSON:", obj.RedisGetJSON("test_json"))

        return True
    except Exception as e:
        print(f"❌ 测试失败: {e}")
        return False

if __name__ == '__main__':
    if len(sys.argv) > 1 and sys.argv[1] == '--test':
        test_redis_com()
    else:
        register_redis_com()
